﻿using System;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Threading.Tasks;
using TemplatesPrint.DBHelper;
using TemplatesPrint.Entitys;
using System.Threading;
using TemplatesPrint.DTO;
using Newtonsoft.Json;
using TemplatesPrint.MySqlEntitys;
using FastReport;
using TemplatesPrint.EntityHandle;
using Newtonsoft.Json.Serialization;
using System.Text;
using System.Net;
using System.IO;
using System.Windows.Forms;
using Sunny.UI;
using System.Net.Http;

namespace TemplatesPrint.Tools
{
    public class PublicTool
    {
        #region 
        public static string ServerDbIp;//服务器数据库地址
        //public static string ServerDbPW;//服务器数据库密码
        //public static string ServerDbPort;//服务器数据库端口
        //public static string ServerDbName;//服务器数据库名
        //public static string ServerDbUser;//服务器数据库用户名
        public static string GetTemplatesType;//获取模板方式  API：请求API获取模板xml  SharedFile：共享文件，获取模板文件  LocalFile：本地文件，获取模板
        public static string TemplatesUrl;//GetTemplatesType为API时， 获取模板url   GetTemplatesType为LocalFile时，获取模板路径

        //GetTemplatesType为SharedFile时
        public static string ServerPW;//服务器共享用户登录密码
        public static string ServerTPath;//服务器模板共享路径
        public static string ServerTIpPath;//服务器模板共享ip
        public static string ServerUser;//服务器共享用户

        #endregion

        public static string WsPort;//websocket server 端口

        public static string Pwd; //修改系统配置密码

        public static bool IsAllPause=false;//任务是否全部暂停

        public static string IpAddress = IpTools.GetIpAddress();//

        public static string MacAddress = IpTools.GetMacAddress();//

        public static string Version="0";//8位日期+3位流水

        public static string PrintCheckNum = "-1"; //打印队列检测频率 <0不检测 

        public static string UpdateUrl= "-1"; //版本更新服务

        public static JsonSerializerSettings serializerSettings = new JsonSerializerSettings
        {
            // 设置为驼峰命名
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };


        public static Dictionary<string, PrintTheadDto> DicPrintTheadDto = new Dictionary<string, PrintTheadDto>();

        public static void InitLoad()
        {
            
            using (var db = SQLiteHelper.GetInstance())
            {
                var configs = db.Queryable<SysConfigEntity>()
                    .OrderBy(x => x.OrderNo).ToList();

                WsPort = configs.Where(c => c.Id == "WsPort").FirstOrDefault()?.Value;

                ServerDbIp = configs.Where(c => c.Id == "ServerDbIp").FirstOrDefault()?.Value;
                //ServerDbPort = configs.Where(c => c.Id == "ServerDbPort").FirstOrDefault()?.Value;

                //ServerDbName = configs.Where(c => c.Id == "ServerDbName").FirstOrDefault()?.Value;
                //ServerDbUser = configs.Where(c => c.Id == "ServerDbUser").FirstOrDefault()?.Value;
                //ServerDbPW = configs.Where(c => c.Id == "ServerDbPW").FirstOrDefault()?.Value;

                ServerTPath = configs.Where(c => c.Id == "ServerTPath").FirstOrDefault()?.Value;
                ServerUser = configs.Where(c => c.Id == "ServerUser").FirstOrDefault()?.Value;
                ServerPW = configs.Where(c => c.Id == "ServerPW").FirstOrDefault()?.Value;
                ServerTIpPath = configs.Where(c => c.Id == "ServerTIpPath").FirstOrDefault()?.Value;

                Pwd = configs.Where(c => c.Id == "Pwd").FirstOrDefault()?.Value;

                GetTemplatesType = configs.Where(c => c.Id == "GetTemplatesType").FirstOrDefault()?.Value;
                TemplatesUrl = configs.Where(c => c.Id == "TemplatesUrl").FirstOrDefault()?.Value;

                UpdateUrl = configs.Where(c => c.Id == "UpdateUrl").FirstOrDefault()?.Value;

                Version = configs.Where(c => c.Id == "Version").FirstOrDefault()?.Value;
                SysConfigEntity ver = new SysConfigEntity
                {
                    Id = "Version",
                    Value = "0"
                };

                if (string.IsNullOrEmpty(Version))
                {
                    Version = "0";
                    db.Insertable(ver).ExecuteCommand();
                }

                string file = Application.StartupPath + @"\UpdateVersionInfo.zl";
                if (File.Exists(file))
                {
                    var txt = File.ReadAllText(file);
                    var info = txt.Split("\r\n");//原版本，新版本，更新后运行的程序，更新服务，完成更新标识
                    if (info.Length >= 4 && info[4] == "Complete")
                    {
                        Version=ver.Value = info[1];

                        db.Updateable(ver).ExecuteCommand();

                        File.Delete(file);
                    }
                }

                PrintCheckNum = configs.Where(c => c.Id == "PrintCheckNum").FirstOrDefault()?.Value;

                if (string.IsNullOrEmpty(PrintCheckNum))
                {
                    PrintCheckNum = "-1";
                }

                var P_Tasks = db.Queryable<TaskInfoEntity>().ToList();

                (new PublicTool()).AddPrintThead(P_Tasks);
                AutoUpLoad.DataUpLoad();

            };
        }

        public  void AddPrintThead(List<TaskInfoEntity> P_Tasks)
        {
            if (P_Tasks != null && P_Tasks.Count > 0)
            {
                var printers = PrinterTool.GetAllPrinter();

                foreach (var t in P_Tasks)
                {
                    string printNmae = t.PrinterInfo;
                    var printer = new PrinterDto();
                    if (string.IsNullOrEmpty(printNmae))
                    {
                        printer = printers.Where(x => x.IsDefault == true).FirstOrDefault();
                        printNmae = printer.PrinterName;
                    }
                    else
                    {
                        printer = printers.Where(x => x.PrinterName == printNmae).FirstOrDefault();
                    }

                    if (DicPrintTheadDto.Keys.Contains(printNmae))
                    {
                        var isExist = DicPrintTheadDto[printNmae].PTaskList.Exists(x => x.Id == t.Id);
                        if (!isExist)
                        {
                            DicPrintTheadDto[printNmae].PTaskList.Add(t);
                        }
                    }
                    else
                    {
                        //PrintTheadTool printTheadTool = new PrintTheadTool();
                        PrintTheadDto pt = new PrintTheadDto();
                        pt.PDto = printer;
                        pt.PTaskList.Add(t);
                        pt.IsRun = true;
                        pt.PThread = new Thread(PrintTheadTool.PrintThread);
                        pt.PThread.IsBackground = true;
                        
                        DicPrintTheadDto.Add(printNmae, pt);

                        pt.PThread.Start(printNmae);
                    }
                }
            }
        }

        public static void UpdatePrintTheadTaskStatus(string printerName, int id, string status)
        {
            var printers = PrinterTool.GetAllPrinter();
            if (string.IsNullOrEmpty(printerName))
            {
                printerName = printers.Where(x => x.IsDefault == true).FirstOrDefault().PrinterName;
            }
            var print = DicPrintTheadDto[printerName];
            var task = print.PTaskList.Where(x => x.Id == id).FirstOrDefault();
            if (task != null)
            {
                task.Status = status;
            }
        }

        public static void RemovePrintTheadTask(string printerName, int id)
        {
            var printers = PrinterTool.GetAllPrinter();
            if (string.IsNullOrEmpty(printerName))
            {
                printerName = printers.Where(x => x.IsDefault == true).FirstOrDefault().PrinterName;
            }
            var print = DicPrintTheadDto[printerName];
            var task = print.PTaskList.Where(x => x.Id == id).FirstOrDefault();
            if (task != null)
            {
                DicPrintTheadDto[printerName].PTaskList.Remove(task);
            }
        }



        /// <summary>
        /// HTTP Get请求
        /// </summary>

        /// <param name="url">API地址</param>

        /// <param name="encode">编码</param>


        public static bool HttpGetData(string url, Encoding encode, out string ret)
        {
            try
            {
                bool ok = true;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                request.ContentType = "text/html, application/xhtml+xml, */*";

                HttpWebResponse response;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();
                }
                catch (WebException ex)
                {
                    ok = false;
                    response = (HttpWebResponse)ex.Response;
                }

                StreamReader sr = new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8); ;
                var result = sr.ReadToEnd();
                sr.Close();
                ret = result;
                return ok;
            }
            catch (Exception ex)
            {
                ret = ex.ToString();
                return false;
            }
        }

        public static bool  PostFormData(string Url, Dictionary<string, string> values, out string ret)
        {

            try
            {
                HttpClient _httpClient = new HttpClient();
                var postContent = new MultipartFormDataContent();
                string boundary = string.Format("--{0}", DateTime.Now.Ticks.ToString("x"));
                postContent.Headers.Add("ContentType", $"multipart/form-data, boundary={boundary}");


                foreach (var keyValuePair in values)
                {
                    postContent.Add(new StringContent(keyValuePair.Value),
                        String.Format("\"{0}\"", keyValuePair.Key));
                }
                HttpResponseMessage response = _httpClient.PostAsync(Url, postContent).Result;
                //var response =  _httpClient.PostAsync(requestUri, postContent);
                //浏览器出参返回入res
                if (response.IsSuccessStatusCode)
                {
                    ret = response.Content.ReadAsStringAsync().Result;
                    return true;
                }
                ret = "服务响应失败！";
                return false;
            }
            catch (WebException ex)
            {
                ret = "获取更新文件失败！请检测服务地址！";
                return false;
            }

        }

        public static bool Post(string Url, string jsonParas, out string ret)
        {
            bool ok = true;
            string strURL = Url;
            //创建一个HTTP请求  
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strURL);
            //Post请求方式  
            request.Method = "POST";
            //内容类型
            request.ContentType = "application/json";
            //设置参数，并进行URL编码 
            string paraUrlCoded = jsonParas;//System.Web.HttpUtility.UrlEncode(jsonParas);   
            byte[] payload;
            //将Json字符串转化为字节  
            payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
            //设置请求的ContentLength   
            request.ContentLength = payload.Length;
            //发送请求，获得请求流 
            Stream writer;
            try
            {
                writer = request.GetRequestStream();//获取用于写入请求数据的Stream对象
            }
            catch (Exception ex)
            {
                writer = null;
                ret = ex.ToString();
                return false;
            }
            //将请求参数写入流
            writer.Write(payload, 0, payload.Length);
            writer.Close();//关闭请求流
                           // String strValue = "";//strValue为http响应所返回的字符流

            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                ok = false;
                response = (HttpWebResponse)ex.Response;
            }

            StreamReader sr = new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8); ;
            var result = sr.ReadToEnd();
            sr.Close();
            ret = result;
            return ok;
        }
    }
}
